package cn.coldleaf.wiki.services.impl;

import cn.coldleaf.wiki.errors.DocSaveException;
import cn.coldleaf.wiki.mappers.DocDraftsMapper;
import cn.coldleaf.wiki.mappers.DocHistoryMapper;
import cn.coldleaf.wiki.mappers.DocMapper;
import cn.coldleaf.wiki.pojo.dto.DocQueryDto;
import cn.coldleaf.wiki.pojo.dto.DocSaveDto;
import cn.coldleaf.wiki.pojo.entity.BaseEntity;
import cn.coldleaf.wiki.pojo.entity.DocDraftsEntity;
import cn.coldleaf.wiki.pojo.entity.DocEntity;
import cn.coldleaf.wiki.pojo.entity.DocHistoryEntity;
import cn.coldleaf.wiki.pojo.vo.DocListVo;
import cn.coldleaf.wiki.pojo.vo.DocVo;
import cn.coldleaf.wiki.services.DocService;
import cn.coldleaf.wiki.services.StreamService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * @datetime 2023/10/20 上午11:08
 * @user cold
 **/
@Slf4j
@Service
@AllArgsConstructor
public class DocServiceImpl implements DocService {
    private final DocMapper docMapper;
    private final DocDraftsMapper docDraftsMapper;
    private final DocHistoryMapper docHistoryMapper;
    private final StreamService streamService;

    /**
     * 创建文档
     *
     * @param dto
     * @datetime 2023-10-20 11:04:10
     * @user cold
     */
    @Override
    @Transactional
    public DocListVo saveDoc(DocSaveDto dto) {
        int ret = 0;
        DocListVo vo = new DocListVo();
        if (dto.getSaveType() == 1){ // 发布
            DocEntity doc = new DocEntity();
            doc.setUserId(dto.getOperator());
            doc.setSpaceId(dto.getSpaceId());
            doc.setParentId(dto.getParentId());
            doc.setTitle(dto.getTitle());
            doc.setContent(dto.getContent());
            doc.setAddUser(dto.getOperator());
            doc.setUpdateUser(dto.getOperator());
            ret = docMapper.insert(doc);
            vo.setId(doc.getId());
            if (ret > 0){
                ret = insertDocHistory(dto, doc);
                if (ret > 0) {
                    // 删除已失效的资源(图片、视频等)
                    ret = removeInvalidRes(dto);
                }
            }
        }else {
            DocDraftsEntity docDrafts = new DocDraftsEntity();
            docDrafts.setDocId(dto.getId() != null ? dto.getId() : 0L);
            docDrafts.setUserId(dto.getOperator());
            docDrafts.setTitle(dto.getTitle());
            docDrafts.setContent(dto.getContent());
            docDrafts.setAddUser(dto.getOperator());
            docDrafts.setUpdateUser(dto.getOperator());
            ret = docDraftsMapper.insert(docDrafts);
            if (docDrafts.getDocId() > 0){
                vo.setId(docDrafts.getDocId());
            }
        }
        if (ret == 0){
            throw new DocSaveException();
        }
        return vo;
    }
    /**
     * 移除失效资源
     * @datetime 2023-10-26 16:57:19
     * @user cold
     **/
    private int removeInvalidRes(DocSaveDto dto) {
        int ret = 0;
        if (dto.getInvalidRes() != null && dto.getInvalidRes().length > 0){
            for (String invalidRes : dto.getInvalidRes()) {
                String [] resArr = invalidRes.split("/");
                String relName = resArr[resArr.length -1];
                String resType = resArr[resArr.length - 2];
                ret = streamService.removeFile(resType,relName);
            }
        }else{ // 没有失效资源，直接返回成功
            ret = 1;
        }
        return ret;
    }

    /**
     * 修改文档
     *
     * @param dto
     * @datetime 2023-10-20 11:04:55
     * @user cold
     */
    @Override
    @Transactional
    public DocListVo modifyDoc(DocSaveDto dto) {
        int ret = 0;
        if (dto.getSaveType() == 1){ // 发布
            DocEntity oldDoc = docMapper.selectById(dto.getId());
            DocEntity doc = new DocEntity();
            if (oldDoc != null){
                boolean isUpdate = false;
                if (dto.getTitle() != null && !dto.getTitle().equals(oldDoc.getTitle())){
                    doc.setTitle(dto.getTitle());
                    isUpdate = true;
                }
                if (dto.getContent() != null && !dto.getContent().equals(oldDoc.getContent())){
                    doc.setContent(dto.getContent());
                    isUpdate = true;
                }
                if (dto.getParentId() != null && !dto.getParentId().equals(oldDoc.getParentId())){
                    doc.setParentId(dto.getParentId());
                    isUpdate = true;
                }
                if (dto.getSpaceId() != null && !dto.getSpaceId().equals(oldDoc.getSpaceId())){
                    doc.setSpaceId(dto.getSpaceId());
                    isUpdate = true;
                }
                if (isUpdate) {
                    doc.setUpdateUser(dto.getOperator());
                    doc.setId(dto.getId());
                    ret = docMapper.updateById(doc);
                }
            }
            if (ret > 0){
                ret = insertDocHistory(dto, oldDoc);
                if (ret > 0) {
                    // 删除已失效的资源(图片、视频等)
                    ret = removeInvalidRes(dto);
                }
            }
        }else {
            DocDraftsEntity docDrafts = new DocDraftsEntity();
            docDrafts.setDocId(dto.getId());
            docDrafts.setUserId(dto.getOperator());
            docDrafts.setTitle(dto.getTitle());
            docDrafts.setContent(dto.getContent());
            docDrafts.setAddUser(dto.getOperator());
            docDrafts.setUpdateUser(dto.getOperator());
            ret = docDraftsMapper.insert(docDrafts);
        }
        if (ret == 0){
            throw new DocSaveException();
        }
        DocListVo vo = new DocListVo();
        vo.setId(dto.getId());
        return vo;
    }
    
    /**
     * 插入文档历史记录
     * @datetime 2023-10-26 16:57:50
     * @user cold
     **/
    private int insertDocHistory(DocSaveDto dto, DocEntity doc) {
        int ret;
        DocHistoryEntity docHistory = new DocHistoryEntity();
        docHistory.setDocId(doc.getId());
        docHistory.setTitle(doc.getTitle());
        docHistory.setContent(doc.getContent());
        docHistory.setAddUser(dto.getOperator());
        docHistory.setUpdateUser(dto.getOperator());
        ret = docHistoryMapper.insert(docHistory);
        return ret;
    }

    /**
     * 删除文档
     *
     * @param dto
     * @datetime 2023-10-20 11:05:29
     * @user cold
     */
    @Override
    @Transactional
    public int removeDoc(DocSaveDto dto) {
        long count = docMapper.selectCount(
                new QueryWrapper<DocEntity>()
                .lambda()
                .eq(DocEntity::getParentId,dto.getId())
        );
        if (count > 0){
            return 0;
        }
        // 删除文档
        int ret = docMapper.deleteById(dto.getId());
        // 删除草稿箱
        count = docDraftsMapper.selectCount(
                new QueryWrapper<DocDraftsEntity>()
                .lambda()
                .eq(DocDraftsEntity::getDocId,dto.getId())
        );
        if (count > 0){
            docDraftsMapper.delete(
                    new QueryWrapper<DocDraftsEntity>()
                    .lambda()
                    .eq(DocDraftsEntity::getDocId,dto.getId())
            );
        }
        // 删除历史记录
        docHistoryMapper.delete(
                new QueryWrapper<DocHistoryEntity>()
                .lambda()
                .eq(DocHistoryEntity::getDocId,dto.getId())
        );
        return ret;
    }

    /**
     * 获取文档列表
     *
     * @param dto
     * @datetime 2023-10-20 11:06:39
     * @user cold
     */
    @Override
    public Page<DocListVo> searchList(DocQueryDto dto) {
        Page<DocListVo> page = new Page<>();
        page.setCurrent(dto.getCurrent());
        page.setMaxLimit(dto.getPageSize().longValue());
        return docMapper.search(page,dto);
    }

    /**
     * 获取文档列表
     * @datetime 2023-10-20 12:11:32
     * @user cold
     **/
    @Override
    public List<DocListVo> getList(DocQueryDto dto) {
        List<DocEntity> docs = docMapper.selectList(
                new QueryWrapper<DocEntity>()
                .lambda()
                .select(BaseEntity::getId,DocEntity::getSpaceId,DocEntity::getParentId,DocEntity::getTitle)
                .eq(DocEntity::getSpaceId,dto.getSpaceId())
        );
        List<DocListVo> vos = new ArrayList<>();
        for (DocEntity doc : docs) {
            DocListVo vo = new DocListVo();
            BeanUtils.copyProperties(doc,vo);
            vos.add(vo);
        }
        return vos;
    }

    /**
     * 获取指定文档信息
     *
     * @param dto
     * @datetime 2023-10-20 11:07:56
     * @user cold
     */
    @Override
    public DocVo getDoc(DocQueryDto dto) {
        DocEntity doc = docMapper.selectById(dto.getId());
        if (doc != null) {
            DocVo vo = new DocVo();
            BeanUtils.copyProperties(doc, vo);
            vo.setResList(streamService.getByDoc(doc.getId()));
            return vo;
        }
        return null;
    }
}
